package tianhao.luo.linkedlist;

/**
 * 双向链表
 * @author: tianhao.luo@hand-china.com 2021/6/14  17:15
 */
public class DoubleLinkedList {

    // 头节点
    private HeroNode2 head = new HeroNode2(0,"","");

    public HeroNode2 getHead() {
        return head;
    }

    /**
     * 展示链表中所有数据
     */
    public void list() {
        // 判断链表是否为空
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }

        // 通过操作临时变量的next指针,来寻找尾部节点
        // 输出信息不要包含头节点
        HeroNode2 temp = head.next;

        while (true) {
            System.out.println("当前节点信息:" + temp.toString());
            // temp节点的next不为空,表示还不是尾部数据
            if (temp.next != null) {
                temp = temp.next;
            } else {
                break;
            }
        }
    }


    /**
     * 给链表添加元素
     * 1.确定链表的尾部节点
     * 2.将尾部节点的next指向当前添加的元素,插入节点的pre指向尾部节点
     *
     * @param heroNode 新加节点
     */
    public void add(HeroNode2 heroNode) {
        // 通过操作临时变量的next指针,来寻找尾部节点
        HeroNode2 temp = head;

        while (true) {
            // temp节点的next不为空,表示还不是尾部数据
            if (temp.next != null) {
                temp = temp.next;
                continue;
            }
            // 是尾部数据了,更新节点的尾部信息
            temp.next = heroNode;
            heroNode.pre = temp;
            break;
        }
    }


    /**
     * 更新同no的节点信息
     *
     * 找出同no的节点数据,从前往后遍历
     * @param heroNode 更新的节点
     */
    public void update(HeroNode2 heroNode){

        HeroNode2 temp = head.next;
        if (temp == null){
            System.out.println("链表为空,无法查找");
            return;
        }
        while (true){
            // 找到结尾都没有
            if (temp == null){
                System.out.println("数据不存在~");
                break;
            }

            if (temp.no == heroNode.no) {
                // 更新
                temp.setName(heroNode.getName());
                temp.setNickName(heroNode.getNickName());
                break;
            }
            // 未找见,后移
            temp = temp.next;
        }
    }



    /**
     * 删除同no的节点
     *
     * 找出同no的节点数据,从前往后遍历
     * 1. 链表中将被删除节点A,将A的前一位的next指向A的next,将后一位的pre指向A的pre
     *
     * @param heroNode 删除
     */
    public void delete(HeroNode2 heroNode){

        HeroNode2 temp = head;
        if (temp.next == null){
            System.out.println("链表为空,无法删除");
            return;
        }

        while (true){
            // 找到结尾都没有
            if (temp == null){
                System.out.println("数据不存在~");
                break;
            }
            // 找到删除节点
            if (temp.no == heroNode.no) {
                // 将该节点的前一位的next指向后一位
                // 将该节点的后一位的pre指向前一位
                if (temp.next !=null){
                    temp.next.pre=temp.pre;
                }
                temp.pre.next=temp.next;
                break;
            }
            // 未找见,后移
            temp = temp.next;
        }
    }



    /**
     * 进行插入时,需要按照heroNode节点的no顺序插入
     * 1.从前往后,找出no恰好刚小于heroNode的no的节点less
     * 2.将heroNode的next更新为less的next,将less的next更新为heroNode;heroNode的pre更新为less,less的next的pre更新为heroNode
     * <p>
     * 特殊情况:
     * 1.链表恰好为空,此时heroNode就是尾部节点
     *
     * @param heroNode 插入的节点
     */
    public void addByOrder(HeroNode2 heroNode) {
        // 找出less节点
        HeroNode2 less = head;

        while (true) {
            if (less.next == null){
                less.next = heroNode;
                break;
            }
            // 从前往后移动,如果插入节点小于less的next节点的no,则插入这个位置
            if (heroNode.getNo() < less.next.getNo()) {
                // 插入操作: 将heroNode放入less和less.next之间
                // 1. 插入节点的next指向less的next,插入节点的pre指向less;less的next的pre指向插入节点,less的next指向插入节点
                // 2. less的next指向插入节点
                heroNode.next = less.next;
                heroNode.pre = less;
                less.next.pre = heroNode;
                less.next = heroNode;
                break;
            } else if (heroNode.getNo() == less.next.getNo()) {
                throw new RuntimeException("插入了相同no的数据");
            }
            // 如果插入节点的no大于less的next节点的no,则less需要后移
            less = less.next;
        }
    }
}
